1. Project Clover database Thu Jul 25 2024 23:21:21 UTC
  2. Package org.joda.time

File DateTimeUtils.java

 

Coverage histogram

../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

44
102
30
5
599
215
55
0.54
3.4
6
1.83

Classes

Class Line # Actions
DateTimeUtils 39 97 0% 50 7
0.957831395.8%
DateTimeUtils.MillisProvider 527 0 - 0 0
-1.0 -
DateTimeUtils.SystemMillisProvider 541 1 0% 1 0
1.0100%
DateTimeUtils.FixedMillisProvider 554 2 0% 2 0
1.0100%
DateTimeUtils.OffsetMillisProvider 578 2 0% 2 0
1.0100%
 

Contributing tests

This file is covered by 3290 tests. .

Source view

1    /*
2    * Copyright 2001-2013 Stephen Colebourne
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package org.joda.time;
17   
18    import java.lang.reflect.Method;
19    import java.text.DateFormatSymbols;
20    import java.util.Collections;
21    import java.util.HashMap;
22    import java.util.LinkedHashMap;
23    import java.util.Locale;
24    import java.util.Map;
25    import java.util.concurrent.atomic.AtomicReference;
26   
27    import org.joda.time.chrono.ISOChronology;
28   
29    /**
30    * DateTimeUtils provide public utility methods for the date-time library.
31    * <p>
32    * DateTimeUtils uses shared static variables which are declared as volatile
33    * for thread-safety. These can be changed during the lifetime of the application
34    * however doing so is generally a bad idea.
35    *
36    * @author Stephen Colebourne
37    * @since 1.0
38    */
 
39    public class DateTimeUtils {
40   
41    /**
42    * The singleton instance of the system millisecond provider.
43    */
44    public static final MillisProvider SYSTEM_MILLIS_PROVIDER = new SystemMillisProvider();
45   
46    /** The millisecond provider currently in use. */
47    private static volatile MillisProvider cMillisProvider = SYSTEM_MILLIS_PROVIDER;
48    /**
49    * The default names.
50    * This is lazily initialized to reduce risks of race conditions at startup.
51    */
52    private static final AtomicReference<Map<String, DateTimeZone>> cZoneNames =
53    new AtomicReference<Map<String,DateTimeZone>>();
54   
55    /**
56    * Restrictive constructor
57    */
 
58  1 toggle protected DateTimeUtils() {
59  1 super();
60    }
61   
62    //-----------------------------------------------------------------------
63    /**
64    * Gets the current time in milliseconds.
65    * <p>
66    * By default this returns <code>System.currentTimeMillis()</code>.
67    * This may be changed using other methods in this class.
68    *
69    * @return the current time in milliseconds from 1970-01-01T00:00:00Z
70    */
 
71  10608 toggle public static final long currentTimeMillis() {
72  10608 return cMillisProvider.getMillis();
73    }
74   
75    /**
76    * Resets the current time to return the system time.
77    * <p>
78    * This method changes the behaviour of {@link #currentTimeMillis()}.
79    * Whenever the current time is queried, {@link System#currentTimeMillis()} is used.
80    *
81    * @throws SecurityException if the application does not have sufficient security rights
82    */
 
83  2961 toggle public static final void setCurrentMillisSystem() throws SecurityException {
84  2961 checkPermission();
85  2961 cMillisProvider = SYSTEM_MILLIS_PROVIDER;
86    }
87   
88    /**
89    * Sets the current time to return a fixed millisecond time.
90    * <p>
91    * This method changes the behaviour of {@link #currentTimeMillis()}.
92    * Whenever the current time is queried, the same millisecond time will be returned.
93    *
94    * @param fixedMillis the fixed millisecond time to use
95    * @throws SecurityException if the application does not have sufficient security rights
96    */
 
97  3091 toggle public static final void setCurrentMillisFixed(long fixedMillis) throws SecurityException {
98  3091 checkPermission();
99  3091 cMillisProvider = new FixedMillisProvider(fixedMillis);
100    }
101   
102    /**
103    * Sets the current time to return the system time plus an offset.
104    * <p>
105    * This method changes the behaviour of {@link #currentTimeMillis()}.
106    * Whenever the current time is queried, {@link System#currentTimeMillis()} is used
107    * and then offset by adding the millisecond value specified here.
108    *
109    * @param offsetMillis the fixed millisecond time to use
110    * @throws SecurityException if the application does not have sufficient security rights
111    */
 
112  2 toggle public static final void setCurrentMillisOffset(long offsetMillis) throws SecurityException {
113  2 checkPermission();
114  2 if (offsetMillis == 0) {
115  1 cMillisProvider = SYSTEM_MILLIS_PROVIDER;
116    } else {
117  1 cMillisProvider = new OffsetMillisProvider(offsetMillis);
118    }
119    }
120   
121    /**
122    * Sets the provider of the current time to class specified.
123    * <p>
124    * This method changes the behaviour of {@link #currentTimeMillis()}.
125    * Whenever the current time is queried, the specified class will be called.
126    *
127    * @param millisProvider the provider of the current time to use, not null
128    * @throws SecurityException if the application does not have sufficient security rights
129    * @since 2.0
130    */
 
131  2 toggle public static final void setCurrentMillisProvider(MillisProvider millisProvider) throws SecurityException {
132  2 if (millisProvider == null) {
133  1 throw new IllegalArgumentException("The MillisProvider must not be null");
134    }
135  1 checkPermission();
136  1 cMillisProvider = millisProvider;
137    }
138   
139    /**
140    * Checks whether the provider may be changed using permission 'CurrentTime.setProvider'.
141    *
142    * @throws SecurityException if the provider may not be changed
143    */
 
144  6055 toggle private static void checkPermission() throws SecurityException {
145  6055 SecurityManager sm = System.getSecurityManager();
146  6055 if (sm != null) {
147  0 sm.checkPermission(new JodaTimePermission("CurrentTime.setProvider"));
148    }
149    }
150   
151    //-----------------------------------------------------------------------
152    /**
153    * Gets the millisecond instant from the specified instant object handling null.
154    * <p>
155    * If the instant object is <code>null</code>, the {@link #currentTimeMillis()}
156    * will be returned. Otherwise, the millis from the object are returned.
157    *
158    * @param instant the instant to examine, null means now
159    * @return the time in milliseconds from 1970-01-01T00:00:00Z
160    */
 
161  4405 toggle public static final long getInstantMillis(ReadableInstant instant) {
162  4405 if (instant == null) {
163  82 return DateTimeUtils.currentTimeMillis();
164    }
165  4323 return instant.getMillis();
166    }
167   
168    //-----------------------------------------------------------------------
169    /**
170    * Gets the chronology from the specified instant object handling null.
171    * <p>
172    * If the instant object is <code>null</code>, or the instant's chronology is
173    * <code>null</code>, {@link ISOChronology#getInstance()} will be returned.
174    * Otherwise, the chronology from the object is returned.
175    *
176    * @param instant the instant to examine, null means ISO in the default zone
177    * @return the chronology, never null
178    */
 
179  4073 toggle public static final Chronology getInstantChronology(ReadableInstant instant) {
180  4073 if (instant == null) {
181  29 return ISOChronology.getInstance();
182    }
183  4044 Chronology chrono = instant.getChronology();
184  4044 if (chrono == null) {
185  1 return ISOChronology.getInstance();
186    }
187  4043 return chrono;
188    }
189   
190    //-----------------------------------------------------------------------
191    /**
192    * Gets the chronology from the specified instant based interval handling null.
193    * <p>
194    * The chronology is obtained from the start if that is not null, or from the
195    * end if the start is null. The result is additionally checked, and if still
196    * null then {@link ISOChronology#getInstance()} will be returned.
197    *
198    * @param start the instant to examine and use as the primary source of the chronology
199    * @param end the instant to examine and use as the secondary source of the chronology
200    * @return the chronology, never null
201    */
 
202  39 toggle public static final Chronology getIntervalChronology(ReadableInstant start, ReadableInstant end) {
203  39 Chronology chrono = null;
204  39 if (start != null) {
205  33 chrono = start.getChronology();
206  6 } else if (end != null) {
207  5 chrono = end.getChronology();
208    }
209  39 if (chrono == null) {
210  1 chrono = ISOChronology.getInstance();
211    }
212  39 return chrono;
213    }
214   
215    //-----------------------------------------------------------------------
216    /**
217    * Gets the chronology from the specified interval object handling null.
218    * <p>
219    * If the interval object is <code>null</code>, or the interval's chronology is
220    * <code>null</code>, {@link ISOChronology#getInstance()} will be returned.
221    * Otherwise, the chronology from the object is returned.
222    *
223    * @param interval the interval to examine, null means ISO in the default zone
224    * @return the chronology, never null
225    */
 
226  4 toggle public static final Chronology getIntervalChronology(ReadableInterval interval) {
227  4 if (interval == null) {
228  1 return ISOChronology.getInstance();
229    }
230  3 Chronology chrono = interval.getChronology();
231  3 if (chrono == null) {
232  1 return ISOChronology.getInstance();
233    }
234  2 return chrono;
235    }
236   
237    //-----------------------------------------------------------------------
238    /**
239    * Gets the interval handling null.
240    * <p>
241    * If the interval is <code>null</code>, an interval representing now
242    * to now in the {@link ISOChronology#getInstance() ISOChronology}
243    * will be returned. Otherwise, the interval specified is returned.
244    *
245    * @param interval the interval to use, null means now to now
246    * @return the interval, never null
247    * @since 1.1
248    */
 
249  86 toggle public static final ReadableInterval getReadableInterval(ReadableInterval interval) {
250  86 if (interval == null) {
251  14 long now = DateTimeUtils.currentTimeMillis();
252  14 interval = new Interval(now, now);
253    }
254  86 return interval;
255    }
256   
257    //-----------------------------------------------------------------------
258    /**
259    * Gets the chronology handling null.
260    * <p>
261    * If the chronology is <code>null</code>, {@link ISOChronology#getInstance()}
262    * will be returned. Otherwise, the chronology is returned.
263    *
264    * @param chrono the chronology to use, null means ISO in the default zone
265    * @return the chronology, never null
266    */
 
267  472695 toggle public static final Chronology getChronology(Chronology chrono) {
268  472695 if (chrono == null) {
269  16438 return ISOChronology.getInstance();
270    }
271  456257 return chrono;
272    }
273   
274    //-----------------------------------------------------------------------
275    /**
276    * Gets the zone handling null.
277    * <p>
278    * If the zone is <code>null</code>, {@link DateTimeZone#getDefault()}
279    * will be returned. Otherwise, the zone specified is returned.
280    *
281    * @param zone the time zone to use, null means the default zone
282    * @return the time zone, never null
283    */
 
284  30065 toggle public static final DateTimeZone getZone(DateTimeZone zone) {
285  30065 if (zone == null) {
286  34 return DateTimeZone.getDefault();
287    }
288  30031 return zone;
289    }
290   
291    //-----------------------------------------------------------------------
292    /**
293    * Gets the period type handling null.
294    * <p>
295    * If the zone is <code>null</code>, {@link PeriodType#standard()}
296    * will be returned. Otherwise, the type specified is returned.
297    *
298    * @param type the time zone to use, null means the standard type
299    * @return the type to use, never null
300    */
 
301  38874 toggle public static final PeriodType getPeriodType(PeriodType type) {
302  38874 if (type == null) {
303  202 return PeriodType.standard();
304    }
305  38672 return type;
306    }
307   
308    //-----------------------------------------------------------------------
309    /**
310    * Gets the millisecond duration from the specified duration object handling null.
311    * <p>
312    * If the duration object is <code>null</code>, zero will be returned.
313    * Otherwise, the millis from the object are returned.
314    *
315    * @param duration the duration to examine, null means zero
316    * @return the duration in milliseconds
317    */
 
318  65 toggle public static final long getDurationMillis(ReadableDuration duration) {
319  65 if (duration == null) {
320  22 return 0L;
321    }
322  43 return duration.getMillis();
323    }
324   
325    //-----------------------------------------------------------------------
326    /**
327    * Checks whether the partial is contiguous.
328    * <p>
329    * A partial is contiguous if one field starts where another ends.
330    * <p>
331    * For example <code>LocalDate</code> is contiguous because DayOfMonth has
332    * the same range (Month) as the unit of the next field (MonthOfYear), and
333    * MonthOfYear has the same range (Year) as the unit of the next field (Year).
334    * <p>
335    * Similarly, <code>LocalTime</code> is contiguous, as it consists of
336    * MillisOfSecond, SecondOfMinute, MinuteOfHour and HourOfDay (note how
337    * the names of each field 'join up').
338    * <p>
339    * However, a Year/HourOfDay partial is not contiguous because the range
340    * field Day is not equal to the next field Year.
341    * Similarly, a DayOfWeek/DayOfMonth partial is not contiguous because
342    * the range Month is not equal to the next field Day.
343    *
344    * @param partial the partial to check
345    * @return true if the partial is contiguous
346    * @throws IllegalArgumentException if the partial is null
347    * @since 1.1
348    */
 
349  216 toggle public static final boolean isContiguous(ReadablePartial partial) {
350  216 if (partial == null) {
351  2 throw new IllegalArgumentException("Partial must not be null");
352    }
353  214 DurationFieldType lastType = null;
354  805 for (int i = 0; i < partial.size(); i++) {
355  600 DateTimeField loopField = partial.getField(i);
356  600 if (i > 0) {
357  386 if (loopField.getRangeDurationField() == null || loopField.getRangeDurationField().getType() != lastType) {
358  9 return false;
359    }
360    }
361  591 lastType = loopField.getDurationField().getType();
362    }
363  205 return true;
364    }
365   
366    //-----------------------------------------------------------------------
367    /**
368    * Gets the {@link DateFormatSymbols} based on the given locale.
369    * <p>
370    * If JDK 6 or newer is being used, DateFormatSymbols.getInstance(locale) will
371    * be used in order to allow the use of locales defined as extensions.
372    * Otherwise, new DateFormatSymbols(locale) will be used.
373    * See JDK 6 {@link DateFormatSymbols} for further information.
374    *
375    * @param locale the {@link Locale} used to get the correct {@link DateFormatSymbols}
376    * @return the symbols
377    * @since 2.0
378    */
 
379  39 toggle public static final DateFormatSymbols getDateFormatSymbols(Locale locale) {
380  39 try {
381  39 Method method = DateFormatSymbols.class.getMethod("getInstance", new Class[] {Locale.class});
382  39 return (DateFormatSymbols) method.invoke(null, new Object[] {locale});
383    } catch (Exception ex) {
384  0 return new DateFormatSymbols(locale);
385    }
386    }
387   
388    //-----------------------------------------------------------------------
389    /**
390    * Gets the default map of time zone names.
391    * <p>
392    * This can be changed by {@link #setDefaultTimeZoneNames}.
393    * <p>
394    * The default set of short time zone names is as follows:
395    * <ul>
396    * <li>UT - UTC
397    * <li>UTC - UTC
398    * <li>GMT - UTC
399    * <li>EST - America/New_York
400    * <li>EDT - America/New_York
401    * <li>CST - America/Chicago
402    * <li>CDT - America/Chicago
403    * <li>MST - America/Denver
404    * <li>MDT - America/Denver
405    * <li>PST - America/Los_Angeles
406    * <li>PDT - America/Los_Angeles
407    * </ul>
408    *
409    * @return the unmodifiable map of abbreviations to zones, not null
410    * @since 2.2
411    */
 
412  8 toggle public static final Map<String, DateTimeZone> getDefaultTimeZoneNames() {
413  8 Map<String, DateTimeZone> names = cZoneNames.get();
414  8 if (names == null) {
415  1 names = buildDefaultTimeZoneNames();
416  1 if (!cZoneNames.compareAndSet(null, names)) {
417  0 names = cZoneNames.get();
418    }
419    }
420  8 return names;
421    }
422   
423    /**
424    * Sets the default map of time zone names.
425    * <p>
426    * The map is copied before storage.
427    *
428    * @param names the map of abbreviations to zones, not null
429    * @since 2.2
430    */
 
431  0 toggle public static final void setDefaultTimeZoneNames(Map<String, DateTimeZone> names) {
432  0 cZoneNames.set(Collections.unmodifiableMap(new HashMap<String, DateTimeZone>(names)));
433    }
434   
 
435  1 toggle private static Map<String, DateTimeZone> buildDefaultTimeZoneNames() {
436    // names from RFC-822 / JDK
437    // this is all very US-centric and dubious, but perhaps it will help some
438  1 Map<String, DateTimeZone> map = new LinkedHashMap<String, DateTimeZone>();
439  1 map.put("UT", DateTimeZone.UTC);
440  1 map.put("UTC", DateTimeZone.UTC);
441  1 map.put("GMT", DateTimeZone.UTC);
442  1 put(map, "EST", "America/New_York");
443  1 put(map, "EDT", "America/New_York");
444  1 put(map, "CST", "America/Chicago");
445  1 put(map, "CDT", "America/Chicago");
446  1 put(map, "MST", "America/Denver");
447  1 put(map, "MDT", "America/Denver");
448  1 put(map, "PST", "America/Los_Angeles");
449  1 put(map, "PDT", "America/Los_Angeles");
450  1 return Collections.unmodifiableMap(map);
451    }
 
452  8 toggle private static void put(Map<String, DateTimeZone> map, String name, String id) {
453  8 try {
454  8 map.put(name, DateTimeZone.forID(id));
455    } catch (RuntimeException ex) {
456    // ignore
457    }
458    }
459    //-------------------------------------------------------------------------
460    /**
461    * Calculates the astronomical Julian Day for an instant.
462    * <p>
463    * The <a href="http://en.wikipedia.org/wiki/Julian_day">Julian day</a> is a well-known
464    * system of time measurement for scientific use by the astronomy community.
465    * It expresses the interval of time in days and fractions of a day since
466    * January 1, 4713 BC (Julian) Greenwich noon.
467    * <p>
468    * Each day starts at midday (not midnight) and time is expressed as a fraction.
469    * Thus the fraction 0.25 is 18:00. equal to one quarter of the day from midday to midday.
470    * <p>
471    * Note that this method has nothing to do with the day-of-year.
472    *
473    * @param epochMillis the epoch millis from 1970-01-01Z
474    * @return the astronomical Julian Day represented by the specified instant
475    * @since 2.2
476    */
 
477  16 toggle public static final double toJulianDay(long epochMillis) {
478    // useful links
479    // http://en.wikipedia.org/wiki/Julian_day#cite_note-13 - Wikipedia
480    // http://aa.usno.navy.mil/data/docs/JulianDate.php" - USNO
481    // http://users.zoominternet.net/~matto/Java/Julian%20Date%20Converter.htm - Julian Date Converter by Matt Oltersdorf
482    // http://ssd.jpl.nasa.gov/tc.cgi#top - CalTech
483  16 double epochDay = epochMillis / 86400000d;
484  16 return epochDay + 2440587.5d;
485    }
486   
487    /**
488    * Calculates the astronomical Julian Day Number for an instant.
489    * <p>
490    * The {@link #toJulianDay(long)} method calculates the astronomical Julian Day
491    * with a fraction based on days starting at midday.
492    * This method calculates the variant where days start at midnight.
493    * JDN 0 is used for the date equivalent to Monday January 1, 4713 BC (Julian).
494    * Thus these days start 12 hours before those of the fractional Julian Day.
495    * <p>
496    * Note that this method has nothing to do with the day-of-year.
497    *
498    * @param epochMillis the epoch millis from 1970-01-01Z
499    * @return the astronomical Julian Day represented by the specified instant
500    * @since 2.2
501    */
 
502  8 toggle public static final long toJulianDayNumber(long epochMillis) {
503  8 return (long) Math.floor(toJulianDay(epochMillis) + 0.5d);
504    }
505   
506    /**
507    * Creates a date-time from a Julian Day.
508    * <p>
509    * Returns the {@code DateTime} object equal to the specified Julian Day.
510    *
511    * @param julianDay the Julian Day
512    * @return the epoch millis from 1970-01-01Z
513    * @since 2.2
514    */
 
515  7 toggle public static final long fromJulianDay(double julianDay) {
516  7 double epochDay = julianDay - 2440587.5d;
517  7 return (long) (epochDay * 86400000d);
518    }
519   
520    //-----------------------------------------------------------------------
521    /**
522    * A millisecond provider, allowing control of the system clock.
523    *
524    * @author Stephen Colebourne
525    * @since 2.0 (previously private)
526    */
 
527    public static interface MillisProvider {
528    /**
529    * Gets the current time.
530    * <p>
531    * Implementations of this method must be thread-safe.
532    *
533    * @return the current time in milliseconds
534    */
535    long getMillis();
536    }
537   
538    /**
539    * System millis provider.
540    */
 
541    static class SystemMillisProvider implements MillisProvider {
542    /**
543    * Gets the current time.
544    * @return the current time in millis
545    */
 
546  10133 toggle public long getMillis() {
547  10133 return System.currentTimeMillis();
548    }
549    }
550   
551    /**
552    * Fixed millisecond provider.
553    */
 
554    static class FixedMillisProvider implements MillisProvider {
555    /** The fixed millis value. */
556    private final long iMillis;
557   
558    /**
559    * Constructor.
560    * @param fixedMillis the millis value
561    */
 
562  3091 toggle FixedMillisProvider(long fixedMillis) {
563  3091 iMillis = fixedMillis;
564    }
565   
566    /**
567    * Gets the current time.
568    * @return the current time in millis
569    */
 
570  473 toggle public long getMillis() {
571  473 return iMillis;
572    }
573    }
574   
575    /**
576    * Offset from system millis provider.
577    */
 
578    static class OffsetMillisProvider implements MillisProvider {
579    /** The millis offset. */
580    private final long iMillis;
581   
582    /**
583    * Constructor.
584    * @param offsetMillis the millis offset
585    */
 
586  1 toggle OffsetMillisProvider(long offsetMillis) {
587  1 iMillis = offsetMillis;
588    }
589   
590    /**
591    * Gets the current time.
592    * @return the current time in millis
593    */
 
594  1 toggle public long getMillis() {
595  1 return System.currentTimeMillis() + iMillis;
596    }
597    }
598   
599    }